home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / blix / blixnetwork.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  9.1 KB  |  394 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*_______________________________________________________________________
  18.  |
  19.  | blixnetwork.c - handles reading and writing to the server
  20.  |
  21.  | This handles the network connection to the world-wide
  22.  | highscore server.
  23.  |
  24.  | (c) 1994 Frans van Hoesel, hoesel@chem.rug.nl
  25.  |              Xtreme Graphics Software
  26.  |
  27. */
  28.  
  29. #include <stdio.h>
  30. #include <sys/types.h>
  31. #include <sys/stat.h>
  32. #include <fcntl.h>
  33. #include <sys/socket.h>
  34. #include <sys/time.h>
  35. #include <netinet/in.h>
  36. #include <arpa/inet.h>
  37. #include <netdb.h>
  38. #include <unistd.h>
  39. #include <string.h>
  40. #include <stdlib.h>
  41. #include <errno.h>
  42. #include <sys/ioctl.h>
  43. #include <limits.h>
  44. #include <bstring.h>
  45. #include <malloc.h>
  46.  
  47. #include "blixnetwork.h"
  48. #include "blixscore_io.h"
  49. #include "blixtmpdir.h"
  50. #include "blix.h"
  51.  
  52. #define SERVER "192.82.208.8:8181"
  53.  
  54. int ioctl (int fildes, int request, ...);
  55. int select (int nfds, fd_set *readfds, fd_set *writefds,
  56.                fd_set *exceptfds, struct timeval *timeout);
  57.  
  58. int initstat=0;
  59. static struct sockaddr_in soc_address;
  60. static int serverfile = -1;
  61.  
  62. int init_connect(void) {
  63.     
  64.     int status;
  65.     char *server;
  66.     char *port;
  67.     char *tmp;
  68.     char host[128];
  69.  
  70.     if (noworld) {
  71.     initstat = -1;
  72.     return initstat;
  73.     }
  74.     soc_address.sin_port = htons(8181);
  75.     server = getenv("BLIXSERVER");
  76.     if (server == NULL || strlen(server) > 126) {
  77.     server = SERVER;
  78.     }
  79.     strcpy(host, server);
  80.  
  81.     port=strchr(host, ':');
  82.     if (port != NULL) {
  83.     *port++ = '\0';
  84.     if (port[0] >= '0' && port[0] <='9')  {
  85.         soc_address.sin_port = htons(atol(port));
  86.     }
  87.     }
  88.  
  89.     for (tmp = host; *tmp != '\0'; tmp++)
  90.     {
  91.     if ((*tmp < '0' || *tmp > '9') && *tmp != '.') {
  92.         fprintf(stderr, "%s: bad internet addres in BLIXSERVER "
  93.             "(should be numeric internet address in "
  94.             "dot notation\n", basename);
  95.         exit(1);
  96.         }
  97.     }
  98.     soc_address.sin_addr.s_addr = inet_addr(host);
  99.     soc_address.sin_family = AF_INET;
  100.  
  101.     errno = 0;
  102.     serverfile = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  103.     if (serverfile == -1) {
  104.     initstat = -1;
  105.     return initstat;
  106.     }
  107.     status = 1;
  108.     ioctl(serverfile, FIONBIO, &status);
  109.     status = connect(serverfile, (struct sockaddr*)&soc_address,
  110.         sizeof(soc_address));
  111.     if ((status == 0) || ((status < 0) &&
  112.         ((errno == EINPROGRESS) || (errno == EAGAIN)))) {
  113.     initstat = 0;
  114.     } else {
  115.     initstat = -1;
  116.     }
  117.     return initstat;
  118. }
  119.  
  120. int make_connect(void) {
  121.     struct timeval timeout;
  122.     int ret;
  123.     fd_set writefds;
  124.     int retry;
  125.     int status;
  126.     
  127.     if (initstat == -1) {
  128.     return -1;
  129.     }
  130.     retry = 100;
  131.     timeout.tv_sec = 0;
  132.     timeout.tv_usec = 100000;
  133.     ret = 0;
  134.     errno = 0;
  135.     while (ret <= 0) {
  136.     if (retry-- < 0) {
  137.         status = -1;
  138.         ret = -1;
  139.     }
  140.     FD_ZERO(&writefds);
  141.     FD_SET(serverfile, &writefds);
  142.     ret = select(FD_SETSIZE, NULL, &writefds, NULL, &timeout);
  143.         if ((ret < 0) && (errno != EALREADY)) {
  144.             status = ret;
  145.             break;
  146.         } else if (ret > 0) {
  147.         status = connect(serverfile, (struct sockaddr*)&soc_address,
  148.             sizeof(soc_address));
  149.         if ((status < 0)&&(errno == EISCONN)) {
  150.         status = 0;
  151.         }
  152.         break;
  153.     } else {
  154.             status = connect(serverfile, (struct sockaddr*)&soc_address,
  155.             sizeof(soc_address));
  156.             if ((status < 0)&&(errno != EALREADY)&&(errno != EAGAIN)&&
  157.             (errno != EISCONN)) {
  158.         break;
  159.             }
  160.     }
  161.     }
  162.     if (status >= 0) {
  163.     ret = 0;
  164.     ioctl(serverfile, FIONBIO, &ret);
  165.     } else {
  166.     close(serverfile);
  167.     serverfile = -1;
  168.     initstat = -1;
  169.     }
  170.     return status;
  171. }
  172.  
  173. int read_server(void *buf, int nbyte) {
  174.     int result;
  175.     
  176.     if (initstat == -1 || serverfile <= 0 || server_ready()) {
  177.     return -1;
  178.     }
  179.     result = read_data(serverfile, buf, nbyte);
  180.     if (result != nbyte && result != - nbyte) {
  181.     return -1;
  182.     }
  183.     return (result);
  184. }
  185.  
  186. int read_serverstr(char *buf) {
  187.     int result;
  188.     
  189.     if (initstat == -1 || serverfile == -1) {
  190.     *buf = '\0';
  191.     return -1;
  192.     }
  193.     if (server_ready() == -1) {
  194.     fprintf(stderr, "%s: world server not ready\n", basename);
  195.     *buf = '\0';
  196.     return -1;
  197.     }
  198.     result = readstr(serverfile, buf);
  199.     if (result < 0) {
  200.     return -1;
  201.     }
  202.     return result;
  203. }
  204.  
  205. int server_ready(void) {
  206.     int ready, ret;
  207.     fd_set readfds;
  208.     struct timeval timeout;
  209.     int retry;
  210.     
  211.     if (serverfile <= 0 || initstat == -1) {
  212.     return -1;
  213.     }
  214.     retry = 100;
  215.     timeout.tv_sec = 0;
  216.     timeout.tv_usec = 100000;
  217.     ready = 0;
  218.     while (!ready) {
  219.     FD_ZERO(&readfds);
  220.     FD_SET(serverfile, &readfds);
  221.     ret = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
  222.     if (ret < 0) {
  223.         close(serverfile);
  224.         initstat = -1;
  225.         serverfile = -1;
  226.         return -1;
  227.     } else if (ret > 0) {
  228.         ready = 1;
  229.     } else if (retry -- < 0) {
  230.         close(serverfile);
  231.         serverfile = -1;
  232.         initstat = -1;
  233.         return -1;
  234.     }
  235.     } 
  236.     return 0;    
  237. }
  238.  
  239. int server_wridy(void) {
  240.     int wridy, ret;
  241.     fd_set writefds;
  242.     struct timeval timeout;
  243.     int retry;
  244.     
  245.     if (serverfile <= 0 || initstat == -1) {
  246.     return -1;
  247.     }
  248.     retry = 100;
  249.     timeout.tv_sec = 0;
  250.     timeout.tv_usec = 100000;
  251.     wridy = 0;
  252.     while (!wridy) {
  253.     FD_ZERO(&writefds);
  254.     FD_SET(serverfile, &writefds);
  255.     ret = select(FD_SETSIZE, NULL, &writefds, NULL, &timeout);
  256.     if (ret < 0) {
  257.         close(serverfile);
  258.         serverfile = -1;
  259.         initstat = -1;
  260.         return -1;
  261.     } else if (ret > 0) {
  262.         wridy = 1;
  263.     } else if (retry -- < 0) {
  264.         close(serverfile);
  265.         serverfile = -1;
  266.         initstat = -1;
  267.         return -1;
  268.     }
  269.     } 
  270.     return 0;    
  271. }
  272.  
  273. /*__________________________________________________________________
  274.  | 
  275.  | read_serverscore - read the score list
  276.  |
  277.  | if the list does not exists, a default one is created.
  278.  |
  279. */
  280.  
  281. int read_serverscore(scorelist_t *scorelist) {
  282.     
  283.     char tmpstr[128];
  284.     char tmpstr2[256];
  285.     int i;
  286.     char *slash;
  287.     
  288.     tmpstr[0] = '\0';
  289.     if (initstat == -1 || serverfile == -1 ||
  290.         read_serverstr(tmpstr) <= 0 || strncmp(tmpstr, "BLIX", 4)) {
  291.     scorelist->game = 1;
  292.     scorelist->id = 1;
  293.     for (i=0; i<7; i++) {
  294.         strcpy(scorelist->names[i], "Blix");
  295.         strcpy(scorelist->hosts[i], "Xtreme Graphics Software");
  296.         *(scorelist->images[i]) = '\0';
  297.         scorelist->scores[i] = 2000 - i * 250;
  298.         scorelist->addrs[i] = 0;
  299.     }
  300.    } else {
  301.     if (read_server(&(scorelist->game), sizeof(long)) < 0) return -1;
  302.     if (read_server(&(scorelist->id), sizeof(long))< 0) return -1;
  303.     for (i=0; i<7; i++) {
  304.         if (read_serverstr(tmpstr) < 0) return -1;
  305.         tmpstr[47] = '\0';
  306.         strcpy(scorelist->names[i], tmpstr);
  307.         if (read_serverstr(tmpstr) < 0) return -1; 
  308.         tmpstr[47] = '\0';
  309.         strcpy(scorelist->hosts[i], tmpstr);
  310.         if (read_serverstr(tmpstr) < 0) return -1;
  311.         if (*tmpstr != '\0') {
  312.         strcpy(tmpstr2, BLIXTMPDIR);
  313.         strcat(tmpstr2, "/");
  314.         slash = strrchr(tmpstr, '/');
  315.         if (slash != NULL) {
  316.             strcat(tmpstr2, slash+1);
  317.             strcpy(scorelist->images[i], tmpstr2);
  318.         } else {
  319.             strcpy(scorelist->images[i], tmpstr);
  320.         }
  321.         } else {
  322.         *(scorelist->images[i]) = '\0';
  323.         }
  324.         if (read_server(&(scorelist->scores[i]), sizeof(long)) < 0)
  325.         return -1;
  326.         if (read_server(&(scorelist->addrs[i]), sizeof(long)) < 0)
  327.         return -1;
  328.     }
  329.     }
  330.     return 0;
  331. }
  332.  
  333. int read_serverimg(scorelist_t *scorelist, int imagenum) {
  334.     char tmpstr[128];
  335.     char tmpstr2[256];
  336.     int img;
  337.     long image_size = 0;
  338.     char *imagedata;
  339.  
  340.     if (read_serverstr(tmpstr) < 0) {
  341.     return -1;
  342.     }
  343.     if (*tmpstr != '\0') {
  344.     strcpy(tmpstr2, BLIXTMPDIR "/");
  345.     strcat(tmpstr2, tmpstr);
  346.     img = open(tmpstr2, O_WRONLY | O_CREAT, 0666);
  347.     if (img < 0) {
  348.         *tmpstr = '\0';
  349.     }
  350.     }
  351.     strcpy(scorelist->images[imagenum], tmpstr);
  352.     if (read_server(&image_size, sizeof(long)) < 0) {
  353.     *(scorelist->images[imagenum]) = '\0';
  354.     return -1;
  355.     }
  356.     if (image_size > 0) {
  357.     imagedata = (char *) malloc(image_size);
  358.     read_server(imagedata, -image_size);
  359.     if (*tmpstr != '\0') {
  360.         write_data(img, imagedata, -image_size);
  361.         close(img);
  362.     }
  363.     free(imagedata);
  364.     }
  365.     return 0;
  366. }
  367.  
  368. int write_server(void *buf, int nbyte) {
  369.     int result;
  370.     if (initstat == -1 || serverfile == 0 || server_wridy()) {
  371.     return -1;
  372.     }
  373.     result = write_data(serverfile, buf, nbyte);
  374.     if (result != nbyte && result != -nbyte) {
  375.     return -1;
  376.     }
  377.     return result;
  378. }
  379.  
  380. int openserver(void) {
  381.     if (initstat == -1)
  382.     return -1;
  383.     if (serverfile != -1) {
  384.     close(serverfile);
  385.     serverfile = -1;
  386.     }
  387.     init_connect();
  388.     return (make_connect());
  389. }
  390. void closeserver(void) {
  391.     close(serverfile);
  392.     serverfile = -1;
  393. }
  394.